package Util;

import myinterface.SelectType;
import myinterface.WindowType;

/**
 *
 * @author KieuOanh
 */
public class FIRWindow implements SelectType, WindowType {

    public double wp;
    public double ws;
    public double As;
    public double Rp;
    //
    public double wc;
    public final double pi = Math.PI;
    public double tr_width;
    //khai bao bien cho cua so chu nhat
    public int M;
    public double alpha;
    public double[] hd;
    public double[] hn;
    public double[] w;
    public double[] db;
    public double hdMax = 0;
    public double hnMax = 0;
    public double hdMin = 0;
    public double hnMin = 0;
    public double wnMax = 0;

    public FIRWindow(int typeSelect, int typeWindow, double wp, double ws, double As, double Rp) {
        this.wp = wp;
        this.ws = ws;
        this.As = As;
        this.Rp = Rp;
        wc = pi * (wp + ws) / 2;
        tr_width = (ws - wp) * pi;
        db = new double[300];
        //////////////////////////////////
        switch (typeSelect) {
            case LOW_PASS:
            case HIGH_PASS:
                switch (typeWindow) {
                    case RECTANGLE:
                        M = (int) ceil(1.8 * pi / tr_width) + 1;
                        alpha = (M - 1) / 2;

                        hd = new double[M];
                        w = new double[M];
                        hn = new double[M];
                        double zero = 1.0 / 5.0 + 1.0 / 5.0 - 1.0 / 10.0 - 1.0 / 10.0 - 1.0 / 10.0 - 1.0 / 10.0;

                        for (int i = 0; i < M; i++) {
                            hd[i] = sin(wc * (i - alpha + zero)) / (pi * (i - alpha + zero));
                            w[i] = 1;
                            hn[i] = hd[i] * w[i];
                            System.out.println("hd[" + i + "]= " + hd[i]);
                        }
                        break;
                        
                    case BARTLETT:
                        M = (int) ceil(6.1 * pi / tr_width) + 1;
                        alpha = (M - 1) / 2;

                        hd = new double[M];
                        w = new double[M];
                        hn = new double[M];

                        for (int i = 0; i <= (M - 1) / 2; i++) {
                            w[i] = 2 * i / (double) (M - 1);
                        }
                        for (int i = (M - 1) / 2; i <= M - 1; i++) {
                            w[i] = 2 - 2 * i / (double) (M - 1);
                        }
                        for (int i = 0; i < M; i++) {
                            hd[i] = sin(wc * (i - alpha)) / (pi * (i - alpha));
                            hn[i] = hd[i] * w[i];
                        }

                        break;
                    case HANNING:
                        M = (int) ceil(6.2 * pi / tr_width) + 1;
                        alpha = (M - 1) / 2;
                        hd = new double[M];
                        for (int i = 0; i < M; i++) {
                            hd[i] = wc / pi * sin(wc * (i - alpha)) / (pi * (i - alpha));
                            w[i] = 0.5 - 0.5 * cos(2 * pi / (M - 1) * i);
                            hn[i] = hd[i] * w[i];
                        }
                        break;
                    case HAMMING:
                        M = (int) ceil(6.3 * pi / tr_width) + 1;
                        alpha = (M - 1) / 2;
                        hd = new double[M];
                        for (int i = 0; i < M; i++) {
                            hd[i] = wc / pi * sin(wc * (i - alpha)) / (pi * (i - alpha));
                            w[i] = 0.54 - 0.46 * cos(2 * pi / (M - 1) * i);
                            hn[i] = hd[i] * w[i];
                        }
                        break;
                    case BLACKMAN:
                        M = (int) ceil(6.6 * pi / tr_width) + 1;
                        alpha = (M - 1) / 2;
                        hd = new double[M];
                        for (int i = 0; i < M; i++) {
                            hd[i] = wc / pi * sin(wc * (i - alpha)) / (pi * (i - alpha));
                            w[i] = 0.42 - 0.5 * cos(2 * pi / (M - 1) * i) + 0.08 * cos(4 * pi / (M - 1) * i);
                            hn[i] = hd[i] * w[i];
                        }
                        break;
                    case KAISER:
                        M = (int) ceil(1.8 * pi / tr_width) + 1;
                        alpha = (M - 1) / 2;
                        hd = new double[M];
                        for (int i = 0; i < M; i++) {
                            hd[i] = wc / pi * sin(wc * (i - alpha)) / (pi * (i - alpha));
                            //chua tinh w, hd
                        }
                        break;
                }

                break;

            case BAND_PASS:
                break;
            case BAND_STOP:
                break;
            case HILBERT:
                break;
            case DIFFERENTIATOR:
                break;
        }
        for (int i = 0; i < M; i++) {
            hdMax = max(hdMax, hd[i]);
            hnMax = max(hnMax, hn[i]);
            hdMin = min(hdMin, hd[i]);
            hnMin = min(hnMin, hn[i]);
            wnMax = max(wnMax, w[i]);
        }

    }

    double max(double x, double y) {
        if (x > y) {
            return x;
        } else {
            return y;
        }
    }

    double min(double x, double y) {
        if (x < y) {
            return x;
        } else {
            return y;
        }
    }

    double sin(double x) {
        return Math.sin(x);
    }

    double cos(double x) {
        return Math.cos(x);
    }

    double ceil(double x) {
        return Math.ceil(x);
    }
}
